frame: Convert to gadgets
authorMatthias Clasen <mclasen@redhat.com>
Thu, 10 Dec 2015 04:00:35 +0000 (23:00 -0500)
committerMatthias Clasen <mclasen@redhat.com>
Wed, 16 Dec 2015 20:15:18 +0000 (15:15 -0500)
As part of this conversion, remove the hardcoded padding around
the label.

Unfortunately, we cannot use the main gadget for drawing the frame
decoration, since we want to draw a custom border instead of the
stock css border that gadgets insist on drawing for us. Therefore,
add an extra gadget with name border and use it just for rendering
the frame.

gtk/gtkframe.c
gtk/theme/Adwaita/_common.scss
gtk/theme/Adwaita/gtk-contained-dark.css
gtk/theme/Adwaita/gtk-contained.css

index a875e58d1d649d55bc4ac11e4d955402ac9d57d6..c50c1df01f0925e626ba460a19ca0d04d87c3a54 100644 (file)
 #include "gtkintl.h"
 #include "gtkbuildable.h"
 #include "gtkwidgetpath.h"
+#include "gtkcssnodeprivate.h"
+#include "gtkcsscustomgadgetprivate.h"
+#include "gtkwidgetprivate.h"
+#include "gtkcontainerprivate.h"
+#include "gtkstylecontextprivate.h"
+#include "gtkcssstylepropertyprivate.h"
+#include "gtklabel.h"
 
 #include "a11y/gtkframeaccessible.h"
 
  *
  * # CSS nodes
  *
- * GtkFrame has a single CSS node with name frame. The style class
- * .flat can appear with it. In the #GtkShortcutsWindow, frames
- * are used with the .keycap style class.
+ * |[<!-- language="plain" -->
+ * frame 
+ * ├── border
+ * ├── <label widget>
+ * ╰── <child>
+ * ]|
+ *
+ * GtkFrame has a main CSS node with name frame and a subnode with
+ * name border. The border node is used to render the visible border.
+ * The style class .flat can appear with the main node. In the
+ * #GtkShortcutsWindow, frames are used with the .keycap style class.
  */
 
 
@@ -79,6 +94,9 @@ struct _GtkFramePrivate
   /* Properties */
   GtkWidget *label_widget;
 
+  GtkCssGadget *gadget;
+  GtkCssGadget *border_gadget;
+
   gint16 shadow_type;
   gfloat label_xalign;
   gfloat label_yalign;
@@ -100,6 +118,7 @@ enum {
 
 static GParamSpec *frame_props[LAST_PROP];
 
+static void gtk_frame_finalize     (GObject      *object);
 static void gtk_frame_set_property (GObject      *object,
                                    guint         param_id,
                                    const GValue *value,
@@ -145,6 +164,34 @@ static void gtk_frame_get_preferred_width_for_height(GtkWidget           *layout
                                                     gint                 width,
                                                     gint                *minimum_height,
                                                     gint                *natural_height);
+static void gtk_frame_state_flags_changed (GtkWidget     *widget,
+                                           GtkStateFlags  previous_state);
+
+static void     gtk_frame_measure        (GtkCssGadget        *gadget,
+                                          GtkOrientation       orientation,
+                                          gint                 for_size,
+                                          gint                *minimum_size,
+                                          gint                *natural_size,
+                                          gint                *minimum_baseline,
+                                          gint                *natural_baseline,
+                                          gpointer             data);
+static void     gtk_frame_allocate       (GtkCssGadget        *gadget,
+                                          const GtkAllocation *allocation,
+                                          int                  baseline,
+                                          GtkAllocation       *out_clip,
+                                          gpointer             data);
+static void     gtk_frame_allocate_border (GtkCssGadget        *gadget,
+                                          const GtkAllocation *allocation,
+                                          int                  baseline,
+                                          GtkAllocation       *out_clip,
+                                          gpointer             data);
+static gboolean gtk_frame_render         (GtkCssGadget        *gadget,
+                                          cairo_t             *cr,
+                                          int                  x,
+                                          int                  y,
+                                          int                  width,
+                                          int                  height,
+                                          gpointer             data);
 
 
 G_DEFINE_TYPE_WITH_CODE (GtkFrame, gtk_frame, GTK_TYPE_BIN,
@@ -163,6 +210,7 @@ gtk_frame_class_init (GtkFrameClass *class)
   widget_class = GTK_WIDGET_CLASS (class);
   container_class = GTK_CONTAINER_CLASS (class);
 
+  gobject_class->finalize = gtk_frame_finalize;
   gobject_class->set_property = gtk_frame_set_property;
   gobject_class->get_property = gtk_frame_get_property;
 
@@ -212,6 +260,7 @@ gtk_frame_class_init (GtkFrameClass *class)
   widget_class->get_preferred_height           = gtk_frame_get_preferred_height;
   widget_class->get_preferred_height_for_width = gtk_frame_get_preferred_height_for_width;
   widget_class->get_preferred_width_for_height = gtk_frame_get_preferred_width_for_height;
+  widget_class->state_flags_changed            = gtk_frame_state_flags_changed;
 
   container_class->remove = gtk_frame_remove;
   container_class->forall = gtk_frame_forall;
@@ -246,6 +295,7 @@ static void
 gtk_frame_init (GtkFrame *frame)
 {
   GtkFramePrivate *priv;
+  GtkCssNode *widget_node;
 
   frame->priv = gtk_frame_get_instance_private (frame); 
   priv = frame->priv;
@@ -254,6 +304,36 @@ gtk_frame_init (GtkFrame *frame)
   priv->shadow_type = GTK_SHADOW_ETCHED_IN;
   priv->label_xalign = 0.0;
   priv->label_yalign = 0.5;
+
+  widget_node = gtk_widget_get_css_node (GTK_WIDGET (frame));
+  priv->gadget = gtk_css_custom_gadget_new_for_node (widget_node,
+                                                     GTK_WIDGET (frame),
+                                                     gtk_frame_measure,
+                                                     gtk_frame_allocate,
+                                                     gtk_frame_render,
+                                                     NULL,
+                                                     NULL);
+  priv->border_gadget = gtk_css_custom_gadget_new ("border",
+                                                       GTK_WIDGET (frame),
+                                                       priv->gadget,
+                                                       NULL,
+                                                       NULL,
+                                                       gtk_frame_allocate_border,
+                                                       NULL,
+                                                       NULL,
+                                                       NULL);
+}
+
+static void
+gtk_frame_finalize (GObject *object)
+{
+  GtkFrame *frame = GTK_FRAME (object);
+  GtkFramePrivate *priv = frame->priv;
+
+  g_clear_object (&priv->border_gadget);
+  g_clear_object (&priv->gadget);
+
+  G_OBJECT_CLASS (gtk_frame_parent_class)->finalize (object);
 }
 
 static void 
@@ -273,7 +353,7 @@ gtk_frame_set_property (GObject         *object,
     case PROP_LABEL_XALIGN:
       gtk_frame_set_label_align (frame, g_value_get_float (value), 
                                 priv->label_yalign);
-      break;
+     break;
     case PROP_LABEL_YALIGN:
       gtk_frame_set_label_align (frame, priv->label_xalign,
                                 g_value_get_float (value));
@@ -579,8 +659,6 @@ gtk_frame_set_shadow_type (GtkFrame      *frame,
                           GtkShadowType  type)
 {
   GtkFramePrivate *priv;
-  GtkWidget *widget;
-  GtkStyleContext *context;
 
   g_return_if_fail (GTK_IS_FRAME (frame));
 
@@ -588,19 +666,13 @@ gtk_frame_set_shadow_type (GtkFrame      *frame,
 
   if ((GtkShadowType) priv->shadow_type != type)
     {
-      widget = GTK_WIDGET (frame);
       priv->shadow_type = type;
 
-      context = gtk_widget_get_style_context (GTK_WIDGET (frame));
       if (type == GTK_SHADOW_NONE)
-        gtk_style_context_add_class (context, GTK_STYLE_CLASS_FLAT);
+        gtk_css_gadget_add_class (priv->border_gadget, GTK_STYLE_CLASS_FLAT);
       else
-        gtk_style_context_remove_class (context, GTK_STYLE_CLASS_FLAT);
+        gtk_css_gadget_remove_class (priv->border_gadget, GTK_STYLE_CLASS_FLAT);
 
-      if (gtk_widget_is_drawable (widget))
-       gtk_widget_queue_draw (widget);
-
-      gtk_widget_queue_resize (widget);
       g_object_notify_by_pspec (G_OBJECT (frame), frame_props[PROP_SHADOW_TYPE]);
     }
 }
@@ -622,87 +694,65 @@ gtk_frame_get_shadow_type (GtkFrame *frame)
   return frame->priv->shadow_type;
 }
 
-static void
-get_padding_and_border (GtkFrame *frame,
-                        GtkBorder *border)
+static gboolean
+gtk_frame_draw (GtkWidget *widget,
+               cairo_t   *cr)
 {
-  GtkStyleContext *context;
-  GtkStateFlags state;
-
-  context = gtk_widget_get_style_context (GTK_WIDGET (frame));
-  state = gtk_style_context_get_state (context);
-
-  gtk_style_context_get_padding (context, state, border);
+  gtk_css_gadget_draw (GTK_FRAME (widget)->priv->gadget, cr);
 
-  if (frame->priv->shadow_type != GTK_SHADOW_NONE)
-    {
-      GtkBorder tmp;
-
-      gtk_style_context_get_border (context, state, &tmp);
-      border->top += tmp.top;
-      border->right += tmp.right;
-      border->bottom += tmp.bottom;
-      border->left += tmp.left;
-    }
+  return FALSE;
 }
 
 static gboolean
-gtk_frame_draw (GtkWidget *widget,
-               cairo_t   *cr)
+gtk_frame_render (GtkCssGadget *gadget,
+                  cairo_t      *cr,
+                  int           x,
+                  int           y,
+                  int           width,
+                  int           height,
+                  gpointer      data)
 {
-  GtkFrame *frame;
+  GtkWidget *widget;
   GtkFramePrivate *priv;
-  GtkStyleContext *context;
-  gint x, y, width, height;
+  gint xc, yc, w, h;
   GtkAllocation allocation;
-  GtkBorder padding;
 
-  frame = GTK_FRAME (widget);
-  priv = frame->priv;
+  widget = gtk_css_gadget_get_owner (gadget);
+  priv = GTK_FRAME (widget)->priv;
+
+  cairo_save (cr);
 
   gtk_widget_get_allocation (widget, &allocation);
-  get_padding_and_border (frame, &padding);
-  context = gtk_widget_get_style_context (widget);
 
-  x = priv->child_allocation.x - allocation.x - padding.left;
-  y = priv->child_allocation.y - allocation.y - padding.top;
-  width = priv->child_allocation.width + padding.left + padding.right;
-  height =  priv->child_allocation.height + padding.top + padding.bottom;
+  /* We want to use the standard gadget drawing for the border,
+   * so we clip out the label allocation in order to get the
+   * frame gap.
+   */
+  xc = priv->label_allocation.x - allocation.x;
+  yc = y;
+  w = priv->label_allocation.width;
+  h = priv->label_allocation.height;
 
-  if (priv->label_widget)
+  if (GTK_IS_LABEL (priv->label_widget))
     {
-      gfloat xalign;
-      gint height_extra;
-      gint x2;
-
-      if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
-        xalign = priv->label_xalign;
-      else
-        xalign = 1 - priv->label_xalign;
+      PangoRectangle ink_rect;
+
+      /* Shrink the clip area for labels, so we get unclipped
+       * frames for the yalign 0.0 and 1.0 cases.
+       */
+      pango_layout_get_pixel_extents (gtk_label_get_layout (GTK_LABEL (priv->label_widget)), &ink_rect, NULL);
+      yc += (h - ink_rect.height) / 2;
+      h = ink_rect.height;
+    }
 
-      height_extra = MAX (0, priv->label_allocation.height - padding.top)
-          - priv->label_yalign * priv->label_allocation.height;
-      y -= height_extra;
-      height += height_extra;
+  cairo_rectangle (cr, 0, 0, allocation.width, allocation.height);
+  cairo_rectangle (cr, xc + w, yc, - w, h);
+  cairo_set_fill_rule (cr, CAIRO_FILL_RULE_WINDING);
+  cairo_clip (cr);
 
-      x2 = padding.left + (priv->child_allocation.width - priv->label_allocation.width - 2 * LABEL_PAD - 2 * LABEL_SIDE_PAD) * xalign + LABEL_SIDE_PAD;
+  gtk_css_gadget_draw (priv->border_gadget, cr);
 
-      gtk_render_background (context, cr, x, y, width, height);
-
-      /* If the label is completely over or under the frame we can omit the gap */
-      if (priv->label_yalign == 0.0 || priv->label_yalign == 1.0)
-        gtk_render_frame (context, cr, x, y, width, height);
-      else
-        gtk_render_frame_gap (context, cr,
-                              x, y, width, height,
-                              GTK_POS_TOP, x2,
-                              x2 + priv->label_allocation.width + 2 * LABEL_PAD);
-    }
-  else
-    {
-      gtk_render_background (context, cr, x, y, width, height);
-      gtk_render_frame (context, cr, x, y, width, height);
-    }
+  cairo_restore (cr);
 
   GTK_WIDGET_CLASS (gtk_frame_parent_class)->draw (widget, cr);
 
@@ -713,61 +763,95 @@ static void
 gtk_frame_size_allocate (GtkWidget     *widget,
                         GtkAllocation *allocation)
 {
-  GtkFrame *frame = GTK_FRAME (widget);
-  GtkFramePrivate *priv = frame->priv;
-  GtkBin *bin = GTK_BIN (widget);
-  GtkAllocation new_allocation;
-  GtkWidget *child;
+  GtkAllocation clip;
 
   gtk_widget_set_allocation (widget, allocation);
 
-  gtk_frame_compute_child_allocation (frame, &new_allocation);
+  gtk_css_gadget_allocate (GTK_FRAME (widget)->priv->gadget,
+                           allocation,
+                           gtk_widget_get_allocated_baseline (widget),
+                           &clip);
 
-  /* If the child allocation changed, that means that the frame is drawn
-   * in a new place, so we must redraw the entire widget.
-   */
-  if (gtk_widget_get_mapped (widget) && !gdk_rectangle_equal (&priv->child_allocation, &new_allocation))
-    {
-      gdk_window_invalidate_rect (gtk_widget_get_window (widget), allocation, FALSE);
-    }
+  gtk_widget_set_clip (widget, &clip);
+}
 
-  child = gtk_bin_get_child (bin);
-  if (child && gtk_widget_get_visible (child))
-    gtk_widget_size_allocate (child, &new_allocation);
+static void
+gtk_frame_allocate (GtkCssGadget        *gadget,
+                    const GtkAllocation *allocation,
+                    int                  baseline,
+                    GtkAllocation       *out_clip,
+                    gpointer             data)
+{
+  GtkWidget *widget;
+  GtkFrame *frame;
+  GtkFramePrivate *priv;
+  GtkAllocation new_allocation;
+  GtkAllocation frame_allocation;
+  gint height_extra;
+  GtkAllocation clip;
+
+  widget = gtk_css_gadget_get_owner (gadget);
+  frame = GTK_FRAME (widget);
+  priv = frame->priv;
 
+  gtk_frame_compute_child_allocation (frame, &new_allocation);
   priv->child_allocation = new_allocation;
 
   if (priv->label_widget && gtk_widget_get_visible (priv->label_widget))
     {
-      GtkBorder padding;
       gint nat_width, width, height;
       gfloat xalign;
 
-      get_padding_and_border (frame, &padding);
-
       if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
        xalign = priv->label_xalign;
       else
        xalign = 1 - priv->label_xalign;
 
       gtk_widget_get_preferred_width (priv->label_widget, NULL, &nat_width);
-      width = new_allocation.width - 2 * LABEL_PAD - 2 * LABEL_SIDE_PAD;
-      width = MIN (width, nat_width);
+      width = MIN (new_allocation.width, nat_width);
+      gtk_widget_get_preferred_height_for_width (priv->label_widget, width, &height, NULL);
 
-      gtk_widget_get_preferred_height_for_width (priv->label_widget, width,
-                                                 &height, NULL);
+      priv->label_allocation.x = new_allocation.x + (new_allocation.width - width) * xalign;
+      priv->label_allocation.y = new_allocation.y - height;
+      priv->label_allocation.height = height;
+      priv->label_allocation.width = width;
 
+      gtk_widget_size_allocate (priv->label_widget, &priv->label_allocation);
 
-      priv->label_allocation.x = priv->child_allocation.x + LABEL_SIDE_PAD +
-       (new_allocation.width - width - 2 * LABEL_PAD - 2 * LABEL_SIDE_PAD) * xalign + LABEL_PAD;
+      height_extra = (1 - priv->label_yalign) * height;
+    }
+  else
+    height_extra = 0;
 
-      priv->label_allocation.width = width;
+  frame_allocation.x = priv->child_allocation.x;
+  frame_allocation.y = priv->child_allocation.y - height_extra;
+  frame_allocation.width = priv->child_allocation.width;
+  frame_allocation.height = priv->child_allocation.height + height_extra;
 
-      priv->label_allocation.y = priv->child_allocation.y - MAX (height, padding.top);
-      priv->label_allocation.height = height;
+  gtk_css_gadget_allocate (priv->border_gadget,
+                           &frame_allocation,
+                           -1,
+                           &clip);
 
-      gtk_widget_size_allocate (priv->label_widget, &priv->label_allocation);
-    }
+  gtk_container_get_children_clip (GTK_CONTAINER (widget), out_clip);
+  gdk_rectangle_union (out_clip, &clip, out_clip);
+}
+
+static void
+gtk_frame_allocate_border (GtkCssGadget        *gadget,
+                           const GtkAllocation *allocation,
+                           int                  baseline,
+                           GtkAllocation       *out_clip,
+                           gpointer             data)
+{
+  GtkWidget *widget;
+  GtkWidget *child;
+
+  widget = gtk_css_gadget_get_owner (gadget);
+
+  child = gtk_bin_get_child (GTK_BIN (widget));
+  if (child && gtk_widget_get_visible (child))
+    gtk_widget_size_allocate (child, (GtkAllocation *)allocation);
 }
 
 static void
@@ -787,188 +871,163 @@ gtk_frame_real_compute_child_allocation (GtkFrame      *frame,
   GtkFramePrivate *priv = frame->priv;
   GtkWidget *widget = GTK_WIDGET (frame);
   GtkAllocation allocation;
-  GtkBorder padding;
-  gint top_margin;
-  gint border_width;
+  gint border_width, height;
 
   gtk_widget_get_allocation (widget, &allocation);
-  get_padding_and_border (frame, &padding);
   border_width = gtk_container_get_border_width (GTK_CONTAINER (frame));
 
   if (priv->label_widget)
     {
-      gint nat_width, width, height;
+      gint nat_width, width;
 
       gtk_widget_get_preferred_width (priv->label_widget, NULL, &nat_width);
-
-      width = allocation.width;
-      width -= 2 * LABEL_PAD + 2 * LABEL_SIDE_PAD;
-      width -= (border_width * 2) + padding.left + padding.right;
-
-      width = MIN (width, nat_width);
-
-      gtk_widget_get_preferred_height_for_width (priv->label_widget, width,
-                                                 &height, NULL);
-
-      top_margin = MAX (height, padding.top);
+      width = MIN (allocation.width - 2 * border_width, nat_width);
+      gtk_widget_get_preferred_height_for_width (priv->label_widget, width, &height, NULL);
     }
   else
-    top_margin = padding.top;
+    height = 0;
+
+  child_allocation->x = allocation.x + border_width;
+  child_allocation->y = allocation.y + border_width + height;
+  child_allocation->width = MAX (1, allocation.width - 2 * border_width);
+  child_allocation->height = MAX (1, allocation.height - 2 * border_width - height);
 
-  child_allocation->x = border_width + padding.left;
-  child_allocation->y = border_width + top_margin;
-  child_allocation->width = MAX (1, (gint) (allocation.width - (border_width * 2) -
-                                           padding.left - padding.right));
-  child_allocation->height = MAX (1, (gint) (allocation.height - child_allocation->y -
-                                            border_width - padding.bottom));
 
-  child_allocation->x += allocation.x;
-  child_allocation->y += allocation.y;
 }
 
 static void
-gtk_frame_get_preferred_size (GtkWidget      *widget,
-                              GtkOrientation  orientation,
-                              gint           *minimum_size,
-                              gint           *natural_size)
+gtk_frame_measure (GtkCssGadget   *gadget,
+                   GtkOrientation  orientation,
+                   int             for_size,
+                   int            *minimum,
+                   int            *natural,
+                   int            *minimum_baseline,
+                   int            *natural_baseline,
+                   gpointer        data)
 {
-  GtkFrame *frame = GTK_FRAME (widget);
-  GtkFramePrivate *priv = frame->priv;
-  GtkBorder padding;
+  GtkWidget *widget;
+  GtkFrame *frame;
+  GtkFramePrivate *priv;
   GtkWidget *child;
-  GtkBin *bin = GTK_BIN (widget);
   gint child_min, child_nat;
-  gint minimum, natural;
   guint border_width;
 
-  get_padding_and_border (frame, &padding);
+  widget = gtk_css_gadget_get_owner (gadget);
+  frame = GTK_FRAME (widget);
+  priv = frame->priv;
+
   border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
 
   if (priv->label_widget && gtk_widget_get_visible (priv->label_widget))
     {
       if (orientation == GTK_ORIENTATION_HORIZONTAL)
         {
-          gtk_widget_get_preferred_width (priv->label_widget,
-                                          &child_min, &child_nat);
-          minimum = child_min + 2 * LABEL_PAD + 2 * LABEL_SIDE_PAD;
-          natural = child_nat + 2 * LABEL_PAD + 2 * LABEL_SIDE_PAD;
+          gtk_widget_get_preferred_width (priv->label_widget, &child_min, &child_nat);
+          *minimum = child_min;
+          *natural = child_nat;
         }
       else
         {
-          gtk_widget_get_preferred_height (priv->label_widget,
-                                           &child_min, &child_nat);
-          minimum = MAX (0, child_min - padding.top);
-          natural = MAX (0, child_nat - padding.top);
+          if (for_size > 0)
+            gtk_widget_get_preferred_height_for_width (priv->label_widget,
+                                                       for_size - 2 * border_width, &child_min, &child_nat);
+          else
+            gtk_widget_get_preferred_height (priv->label_widget, &child_min, &child_nat);
+
+          *minimum = child_min;
+          *natural = child_nat;
         }
     }
   else
     {
-      minimum = 0;
-      natural = 0;
+      *minimum = 0;
+      *natural = 0;
     }
 
-  child = gtk_bin_get_child (bin);
+  child = gtk_bin_get_child (GTK_BIN (widget));
   if (child && gtk_widget_get_visible (child))
     {
       if (orientation == GTK_ORIENTATION_HORIZONTAL)
         {
-          gtk_widget_get_preferred_width (child,
-                                          &child_min, &child_nat);
-          minimum = MAX (minimum, child_min);
-          natural = MAX (natural, child_nat);
+          gtk_widget_get_preferred_width (child, &child_min, &child_nat);
+          *minimum = MAX (*minimum, child_min);
+          *natural = MAX (*natural, child_nat);
         }
       else
         {
-          gtk_widget_get_preferred_height (child,
-                                           &child_min, &child_nat);
-          minimum += child_min;
-          natural += child_nat;
-        }
-    }
+          if (for_size > 0)
+            gtk_widget_get_preferred_height_for_width (child, for_size - 2 * border_width, &child_min, &child_nat);
+          else
+            gtk_widget_get_preferred_height (child, &child_min, &child_nat);
 
-  if (orientation == GTK_ORIENTATION_HORIZONTAL)
-    {
-      minimum += (border_width * 2) + padding.left + padding.right;
-      natural += (border_width * 2) + padding.left + padding.right;
-    }
-  else
-    {
-      minimum += (border_width * 2) + padding.top + padding.bottom;
-      natural += (border_width * 2) + padding.top + padding.bottom;
+          *minimum += child_min;
+          *natural += child_nat;
+        }
     }
 
-  *minimum_size = minimum;
-  *natural_size = natural;
+  *minimum += 2 * border_width;
+  *natural += 2 * border_width;
 }
 
 static void
 gtk_frame_get_preferred_width (GtkWidget *widget,
-                               gint      *minimum_size,
-                               gint      *natural_size)
+                               gint      *minimum,
+                               gint      *natural)
 {
-  gtk_frame_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size);
+  gtk_css_gadget_get_preferred_size (GTK_FRAME (widget)->priv->gadget,
+                                     GTK_ORIENTATION_HORIZONTAL,
+                                     -1,
+                                     minimum, natural,
+                                     NULL, NULL);
+}
+
+static void
+gtk_frame_get_preferred_width_for_height (GtkWidget *widget,
+                                          gint       height,
+                                          gint      *minimum,
+                                          gint      *natural)
+{
+  gtk_css_gadget_get_preferred_size (GTK_FRAME (widget)->priv->gadget,
+                                     GTK_ORIENTATION_HORIZONTAL,
+                                     height,
+                                     minimum, natural,
+                                     NULL, NULL);
 }
 
 static void
 gtk_frame_get_preferred_height (GtkWidget *widget,
-                                gint      *minimum_size,
-                                gint      *natural_size)
+                                gint      *minimum,
+                                gint      *natural)
 {
-  gtk_frame_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size);
+  gtk_css_gadget_get_preferred_size (GTK_FRAME (widget)->priv->gadget,
+                                     GTK_ORIENTATION_VERTICAL,
+                                     -1,
+                                     minimum, natural,
+                                     NULL, NULL);
 }
 
 
 static void
 gtk_frame_get_preferred_height_for_width (GtkWidget *widget,
                                           gint       width,
-                                          gint      *minimum_height,
-                                          gint      *natural_height)
+                                          gint      *minimum,
+                                          gint      *natural)
 {
-  GtkWidget *child;
-  GtkFrame *frame = GTK_FRAME (widget);
-  GtkFramePrivate *priv = frame->priv;
-  GtkBin *bin = GTK_BIN (widget);
-  GtkBorder padding;
-  gint child_min, child_nat, label_width;
-  gint minimum, natural;
-  guint border_width;
-
-  get_padding_and_border (frame, &padding);
-  border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
-
-  minimum = (border_width * 2) + padding.top + padding.bottom;
-  natural = (border_width * 2) + padding.top + padding.bottom;
-
-  width -= (border_width * 2) + padding.left + padding.right;
-  label_width = width - 2 * LABEL_PAD + 2 * LABEL_SIDE_PAD;
-
-  if (priv->label_widget && gtk_widget_get_visible (priv->label_widget))
-    {
-      gtk_widget_get_preferred_height_for_width (priv->label_widget,
-                                                 label_width, &child_min, &child_nat);
-      minimum += child_min;
-      natural += child_nat;
-    }
-
-  child = gtk_bin_get_child (bin);
-  if (child && gtk_widget_get_visible (child))
-    {
-      gtk_widget_get_preferred_height_for_width (child,
-                                                 width, &child_min, &child_nat);
-      minimum += child_min;
-      natural += child_nat;
-    }
-
-  *minimum_height = minimum;
-  *natural_height = natural;
+  gtk_css_gadget_get_preferred_size (GTK_FRAME (widget)->priv->gadget,
+                                     GTK_ORIENTATION_VERTICAL,
+                                     width,
+                                     minimum, natural,
+                                     NULL, NULL);
 }
 
 static void
-gtk_frame_get_preferred_width_for_height (GtkWidget *widget,
-                                          gint       height,
-                                          gint      *minimum_width,
-                                          gint      *natural_width)
+gtk_frame_state_flags_changed (GtkWidget     *widget,
+                               GtkStateFlags  previous_state)
 {
-  GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget, minimum_width, natural_width);
-}
+  GtkCssNode *border_node;
 
+  border_node = gtk_css_gadget_get_node (GTK_FRAME (widget)->priv->border_gadget);
+  gtk_css_node_set_state (border_node, gtk_widget_get_state_flags (widget));
+
+  GTK_WIDGET_CLASS (gtk_frame_parent_class)->state_flags_changed (widget, previous_state);
+}
index 81aa7f2ad7d0b14c54a4d9089af8a4e4eeae3b78..c6e2a02a67027a38d008fb7f7f46e0f5a76cec3d 100644 (file)
@@ -2496,12 +2496,15 @@ levelbar {
 /**********
  * Frames *
  **********/
-frame,
+frame border,
 .frame {
+  box-shadow: none;
+  margin: 0;
+  padding: 0;
+  border-radius: 0;
   border: 1px solid $borders_color;
   &.flat { border-style: none; }
   &:backdrop { border-color: $backdrop_borders_color; }
-  padding: 0;
 }
 
 paper {
index 4ac01b1ed4a791f830383962a9177ff30576dda3..eadf160c6d9971852f0e34d399686574997145c9 100644 (file)
@@ -3483,14 +3483,17 @@ levelbar {
 /**********
  * Frames *
  **********/
-frame,
+frame border,
 .frame {
-  border: 1px solid #1c1f1f;
-  padding: 0; }
-  frame.flat,
+  box-shadow: none;
+  margin: 0;
+  padding: 0;
+  border-radius: 0;
+  border: 1px solid #1c1f1f; }
+  frame border.flat,
   .frame.flat {
     border-style: none; }
-  frame:backdrop,
+  frame border:backdrop,
   .frame:backdrop {
     border-color: #1f2222; }
 
index 94fadd4c25503b852021d4af6dc4717c836d7793..d6d42b4d419596b1a61cb72e5d3b7abd69c8a202 100644 (file)
@@ -3645,14 +3645,17 @@ levelbar {
 /**********
  * Frames *
  **********/
-frame,
+frame border,
 .frame {
-  border: 1px solid #9d9d99;
-  padding: 0; }
-  frame.flat,
+  box-shadow: none;
+  margin: 0;
+  padding: 0;
+  border-radius: 0;
+  border: 1px solid #9d9d99; }
+  frame border.flat,
   .frame.flat {
     border-style: none; }
-  frame:backdrop,
+  frame border:backdrop,
   .frame:backdrop {
     border-color: #a5a5a1; }